using System.Collections;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using System.Threading;
using GHIElectronics.NETMF.FEZ;
using GHIElectronics.NETMF.Hardware;

namespace Soigeneris
{
    class UserInterface
    {
        static TestConfig config;
        static TestPort_OnBoard myTestPort;
        static LCDLiveText liveText = LCDLiveText.Instance;

        public UserInterface()
        {
            loadTest();
    
            liveText.Print("Cable Tester");
            liveText.Print("Select to Start");
            FEZ_Shields.KeypadLCD.TurnBacklightOn(75);
            waitForKey(FEZ_Shields.KeypadLCD.Keys.Select);

            liveText.Clear();
            liveText.Print("Select to Test");

            liveText.KeyEvent += new KeyEventHandler(keyPressed);
            

            Thread.Sleep(Timeout.Infinite); // just it case menu returns
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="key"></param>
        private void waitForKey(FEZ_Shields.KeypadLCD.Keys key)
        {
            while (FEZ_Shields.KeypadLCD.GetKey() != key)
            {
                Thread.Sleep(100);
            }
        }

        // This will be called whenever the list changes.
        private void keyPressed(object sender, KeyEventArgs e)
        {
            switch (e.key)
            {
                case FEZ_Shields.KeypadLCD.Keys.Select:
                    System.Threading.Thread testThread = new Thread(doSelect);
                    testThread.Start();
                    break;

                case FEZ_Shields.KeypadLCD.Keys.Right:
                    liveText.Scroll(LCDLiveText.ScrollDirection.Right);
                    break;

                case FEZ_Shields.KeypadLCD.Keys.Left:
                    liveText.Scroll(LCDLiveText.ScrollDirection.Left);
                    break;

                case FEZ_Shields.KeypadLCD.Keys.Up:
                    liveText.Scroll(LCDLiveText.ScrollDirection.Up);
                    break;

                case FEZ_Shields.KeypadLCD.Keys.Down:
                    liveText.Scroll(LCDLiveText.ScrollDirection.Down);
                    break;
            }
        }


        /// <summary>
        /// Perform test(s)
        /// </summary>
        /// <param name="myTestPort"></param>
        void doSelect(/*TestPort myTestPort*/)
        {
            liveText.Clear();
            liveText.Print("Digital Test");
            myTestPort.Reset(); // rest last results before running new set of tests

            // If the result == false then the test failed, the results of the test
            // will be saved in TestPort.myLastTest
            bool result = true;
            for (int t = 0; t < config.TestCount; t++)
            {
                liveText.Clear();
                TestConfig.Test test = config.GetTest(t);
                liveText.Print("Running " + test.Name); // Comment these two lines for speed
                Thread.Sleep(1000);                     // This just helps to see what is happening
                result &= myTestPort.digitalTest(config.GetTest(t));
            }

            if (result)
            {
                liveText.Clear();
                liveText.Print("Passed");
            }
            else
            {
                liveText.Clear();
                liveText.Print("Failed");

                for (int i = 0; myTestPort.myLastTest.dResult.Count > 0; i++)
                {
                    Debug.Print("Queue count" + myTestPort.myLastTest.dResult.Count.ToString());
                    TestPort.DigitalResult res = (TestPort.DigitalResult)myTestPort.myLastTest.dResult.Dequeue();
                    TestConfig.ConnectorPinMap driveMap = config.Point2PinMap((TestPoint)res.drivePin);
                    TestConfig.ConnectorPinMap drivenMap = config.Point2PinMap((TestPoint)res.drivenPin);

                    string resText = (res.reading) ? " Shorted " : " Open ";
                    liveText.Print(driveMap.ConnectorName + "P" + (driveMap.Pin).ToString()
                        + resText + drivenMap.ConnectorName + "P" + (drivenMap.Pin).ToString());
                }

            }
            liveText.Print("Select to Test");
        }

        void loadTest(/*string path*/)
        {
            // read the test configuration from SD card 
            // and create a TestPort instance
            config = ReadXML.Read(@"\Tests\Test4a.tst");
            myTestPort = TestPort_OnBoard.Instance;

            // Look through the configuration loaded in and register all
            // TestPoints that are being used.
            for (int i = 0; i < config.ConnectorCount; i++)
            {
                TestConfig.Connector con = config.GetConnector(i);
                for (int j = 1; j < con.PinCount + 1; j++)
                {
                    myTestPort.myUsedPins.addDigitalPin(con.Pin2Point(j));
                }
            }
        }
    }
}
